home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 2
/
Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso
/
Aminet
/
gfx
/
edit
/
TSMrph23s.lha
/
TSM23s.lha
/
Subroutines.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-08
|
59KB
|
2,335 lines
// TSMorph - Amiga Morphing program
// Copyright (C) © 1993 Topicsave Limited
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// mpaddock@cix.compulink.co.uk
// $Author: M_J_Paddock $
// $Date: 1993/09/04 17:43:32 $
// $Revision: 1.15 $
// include precompiled headers if required
#ifndef TSMORPH_H
#include "TSMorph.h"
#endif
extern char TempFilename[256]=""; // file name buffer set up and used in various places
UBYTE r[256],g[256],b[256]; // Saved rgb colors
/* display short help message
* at top of window
* helpnum : number of help node
*/
void
ihelp(ULONG helpnum) {
// only display if not zero, and there is a short message and the window is open
if (helpnum) {
if (*(ShortHelp[helpnum])) {
if (TSMorphWnd) {
GT_SetGadgetAttrs(TSMorphGadgets[GDX_Help],TSMorphWnd,NULL,
GTTX_Text,ShortHelp[helpnum], TAG_END );
}
}
}
}
/* Display help using amigaguide (if available)
* based on a number. Also displays short help message
*/
void
help(ULONG helpnum) {
// display amigaguide if available
if (handle) {
SetAmigaGuideContext(handle,helpnum,NULL);
SendAmigaGuideContext(handle,NULL);
}
// display short message
ihelp(helpnum);
}
/* Colour the picture based on it colormap
* Saving the palette for later use
* The palette is only set when the window is active and a menu is not displayed
*/
void
ColorWindow(struct Picture *pic) {
UWORD i; // Loop counter
UWORD color; // Colour
if (palette) {
if (pic) {
if (pic->ilbm->colortable) {
// Store and set up to 256 colours
for (i=0; i<min((1 << pic->Win->WScreen->BitMap.Depth),256); i++) {
color = GetRGB4(pic->Win->WScreen->ViewPort.ColorMap,i);
r[i]=(color&0x0f00)>>8;
g[i]=(color&0x00f0)>>4;
b[i]=(color&0x000f);
}
LoadRGB4(&(pic->Win->WScreen->ViewPort),pic->ilbm->colortable,
MIN(pic->ilbm->ncolors,pic->Win->WScreen->ViewPort.ColorMap->Count));
}
}
}
}
/* Reset the palette to the original
* stored in ColorWindow()
* Called when window becomes inactive or menu is to be displayed
*
* Note: This routine and the one above are not really allowed by CBM
* But if no other program is changing the palette whilst its
* window is inactive then everything should (amy) be OK.
*/
void
UnColorWindow(struct Picture *pic) {
UWORD i; // Loop counter
if (palette) {
if (pic) {
if (pic->ilbm->colortable) {
for (i=0; i<min((1 << pic->Win->WScreen->BitMap.Depth),256); i++) {
SetRGB4(&(pic->Win->WScreen->ViewPort),i,r[i],g[i],b[i]);
}
}
}
}
}
/* Standard CloseWindowSafely
* removing messages on shared ports
*/
void
CloseWindowSafely(struct Window *win) {
Forbid();
StripIntuiMessages(win->UserPort,win);
win->UserPort = NULL;
ModifyIDCMP(win,0);
Permit();
CloseWindow(win);
}
/* Standard StripIntuiMessages */
void
StripIntuiMessages(struct MsgPort *mp,struct Window *win) {
struct IntuiMessage *msg, *succ;
msg = (struct IntuiMessage *)mp->mp_MsgList.lh_Head;
while(succ = (struct IntuiMessage *)msg->ExecMessage.mn_Node.ln_Succ) {
if(msg->IDCMPWindow == win) {
Remove((struct Node *)msg);
ReplyMsg((struct Message *)msg);
}
msg = succ;
}
}
/* Display an error message
* ErrorMessage : The main text
* Gadget : Text for one gadget
* extra : more of the text
* helpnum : Number of a help node
*
* Uses reqtools.library if available
*/
void
Error(char *ErrorMessage,char *Gadget,char *extra,ULONG helpnum) {
struct EasyStruct EasyStruct = {
sizeof(struct EasyStruct),
0,
NULL,
NULL,
NULL
};
UBYTE *title = "TSMorph Error";
struct Window *req;
UBYTE gad[32] = "Help|";
UBYTE gad1[32] = "_Help|_";
ULONG ret = CALL_HANDLER;
struct AmigaGuideMsg *agm;
ULONG signals;
struct rtHandlerInfo *rth;
// Disable the windows and display the requester
DisableWindows(helpnum);
if (ReqToolsBase) {
// Set up gadgets depending on if amigaguide is available
if (!handle) {
strcpy(gad1,"_");
}
strcat(gad1,Gadget);
// This loops until OK is pressed, displaying help if Help is pressed (if present)
while (ret) {
ret = CALL_HANDLER;
if (rtEZRequestTags(ErrorMessage,gad1,NULL,&extra,
RT_ReqHandler, &rth,
RT_Window, TSMorphWnd,
RT_Underscore, '_',
RTEZ_ReqTitle, title,
TAG_END) == CALL_HANDLER) {
while (ret == CALL_HANDLER) {
if (!rth->DoNotWait) {
signals = Wait(rth->WaitMask | ASig);
}
ret = rtReqHandlerA(rth,signals,NULL);
if (ret == 1) {
help(helpnum);
}
if (signals & ASig) {
while (agm = GetAmigaGuideMsg(handle)) {
ReplyAmigaGuideMsg(agm);
}
}
}
}
else {
ret = 0;
}
}
}
else {
EasyStruct.es_TextFormat = ErrorMessage;
EasyStruct.es_Title = title;
// Set up gadgets depending on if amigaguide is available
if (handle) {
strcat(gad,Gadget);
}
else {
strcpy(gad,Gadget);
}
EasyStruct.es_GadgetFormat = gad;
req = BuildEasyRequest(TSMorphWnd,&EasyStruct,NULL,extra);
// This loops until OK is pressed, displaying help if Help is pressed (if present)
while (ret) {
signals = Wait((1L << req->UserPort->mp_SigBit) | ASig);
if (signals & (1L << req->UserPort->mp_SigBit)) {
ret = SysReqHandler(req,NULL,FALSE);
if (ret == 1) {
help(helpnum);
}
}
if (signals & ASig) {
while (agm = GetAmigaGuideMsg(handle)) {
ReplyAmigaGuideMsg(agm);
}
}
}
FreeSysRequest(req);
}
EnableWindows();
}
/* As Error but
* pic : a picture to uncolor if required
*/
void
XError(struct Picture *pic,char *ErrorMessage,char *Gadget,char *extra,ULONG helpnum) {
UnColorWindow(pic);
Error(ErrorMessage,Gadget,extra,helpnum);
ColorWindow(pic);
}
/* Draw all points
* in both windows
*/
void
DrawAllPoints(void) {
struct MyPoint *MyPoint;
// For each point
for (MyPoint = (struct MyPoint *)PointList.lh_Head;
MyPoint->MyNode.mln_Succ;
MyPoint = (struct MyPoint *)MyPoint->MyNode.mln_Succ) {
// Draw point in image 1
DrawPixels(&Pic1,MyPoint->x,MyPoint->y,NULL);
/* For each linked point draw a line
* to the other if the other is a "later" point
*/
if (MyPoint->p1 > MyPoint) {
MyDraw(Pic1.Win->RPort,MyPoint->p1->x<<Zoom,MyPoint->p1->y<<Zoom,MyPoint->x<<Zoom,MyPoint->y<<Zoom);
}
if (MyPoint->p2 > MyPoint) {
MyDraw(Pic1.Win->RPort,MyPoint->p2->x<<Zoom,MyPoint->p2->y<<Zoom,MyPoint->x<<Zoom,MyPoint->y<<Zoom);
}
if (MyPoint->p3 > MyPoint) {
MyDraw(Pic1.Win->RPort,MyPoint->p3->x<<Zoom,MyPoint->p3->y<<Zoom,MyPoint->x<<Zoom,MyPoint->y<<Zoom);
}
if (MyPoint->p4 > MyPoint) {
MyDraw(Pic1.Win->RPort,MyPoint->p4->x<<Zoom,MyPoint->p4->y<<Zoom,MyPoint->x<<Zoom,MyPoint->y<<Zoom);
}
// Same stuff for image 2
DrawPixels(&Pic2,MyPoint->x1,MyPoint->y1,NULL);
if (MyPoint->p1 > MyPoint) {
MyDraw(Pic2.Win->RPort,MyPoint->p1->x1<<Zoom,MyPoint->p1->y1<<Zoom,MyPoint->x1<<Zoom,MyPoint->y1<<Zoom);
}
if (MyPoint->p2 > MyPoint) {
MyDraw(Pic2.Win->RPort,MyPoint->p2->x1<<Zoom,MyPoint->p2->y1<<Zoom,MyPoint->x1<<Zoom,MyPoint->y1<<Zoom);
}
if (MyPoint->p3 > MyPoint) {
MyDraw(Pic2.Win->RPort,MyPoint->p3->x1<<Zoom,MyPoint->p3->y1<<Zoom,MyPoint->x1<<Zoom,MyPoint->y1<<Zoom);
}
if (MyPoint->p4 > MyPoint) {
MyDraw(Pic2.Win->RPort,MyPoint->p4->x1<<Zoom,MyPoint->p4->y1<<Zoom,MyPoint->x1<<Zoom,MyPoint->y1<<Zoom);
}
}
}
/* Handle Raw Key in Information
* Window - from GadToolsBox
*/
int
TSMorphRawKey(void) {
UWORD X,Y; // Mouse position
ULONG HNum; // Help node
X = TSMorphWnd->MouseX;
Y = TSMorphWnd->MouseY;
switch (TSMorphMsg.Code) {
// only help key does anything
case 0x5f:
/* Find gadget pointer is in
* otherwise use whole window
*/
if (PointInBox(X,Y,Rect[GDX_Help].MinX,Rect[GDX_Help].MinY,
Rect[GDX_Help].MaxX,Rect[GDX_Help].MaxY))
HNum = H_HelpGad;
else
if (PointInBox(X,Y,Rect[GDX_GetFile1].MinX,Rect[GDX_GetFile1].MinY,
Rect[GDX_GetFile1].MaxX,Rect[GDX_GetFile1].MaxY))
HNum = H_G24File1;
else
if (PointInBox(X,Y,Rect[GDX_GetFile2].MinX,Rect[GDX_GetFile2].MinY,
Rect[GDX_GetFile2].MaxX,Rect[GDX_GetFile2].MaxY))
HNum = H_G24File2;
else
if (PointInBox(X,Y,Rect[GDX_Width].MinX,Rect[GDX_Width].MinY,
Rect[GDX_Width].MaxX,Rect[GDX_Width].MaxY))
HNum = H_Width;
else
if (PointInBox(X,Y,Rect[GDX_Height].MinX,Rect[GDX_Height].MinY,
Rect[GDX_Height].MaxX,Rect[GDX_Height].MaxY))
HNum = H_Height;
else
if (PointInBox(X,Y,Rect[GDX_GetFileOne].MinX,Rect[GDX_GetFileOne].MinY,
Rect[GDX_GetFileOne].MaxX,Rect[GDX_GetFileOne].MaxY))
HNum = H_GFileOne;
else
if (PointInBox(X,Y,Rect[GDX_GetFileTwo].MinX,Rect[GDX_GetFileTwo].MinY,
Rect[GDX_GetFileTwo].MaxX,Rect[GDX_GetFileTwo].MaxY))
HNum = H_GFileTwo;
else
if (PointInBox(X,Y,Rect[GDX_EditPoints].MinX,Rect[GDX_EditPoints].MinY,
Rect[GDX_EditPoints].MaxX,Rect[GDX_EditPoints].MaxY))
HNum = H_EPoints;
else
if (PointInBox(X,Y,Rect[GDX_SinglePicture].MinX,Rect[GDX_SinglePicture].MinY,
Rect[GDX_SinglePicture].MaxX,Rect[GDX_SinglePicture].MaxY))
HNum = H_Single;
else
if (PointInBox(X,Y,Rect[GDX_GetSaveName].MinX,Rect[GDX_GetSaveName].MinY,
Rect[GDX_GetSaveName].MaxX,Rect[GDX_GetSaveName].MaxY))
HNum = H_GName;
else
if (PointInBox(X,Y,Rect[GDX_FileOne].MinX,Rect[GDX_FileOne].MinY,
Rect[GDX_FileOne].MaxX,Rect[GDX_FileOne].MaxY))
HNum = H_FileOne;
else
if (PointInBox(X,Y,Rect[GDX_FileTwo].MinX,Rect[GDX_FileTwo].MinY,
Rect[GDX_FileTwo].MaxX,Rect[GDX_FileTwo].MaxY))
HNum = H_FileTwo;
else
if (PointInBox(X,Y,Rect[GDX_File241].MinX,Rect[GDX_File241].MinY,
Rect[GDX_File241].MaxX,Rect[GDX_File241].MaxY))
HNum = H_24File1;
else
if (PointInBox(X,Y,Rect[GDX_File242].MinX,Rect[GDX_File242].MinY,
Rect[GDX_File242].MaxX,Rect[GDX_File242].MaxY))
HNum = H_24File2;
else
if (PointInBox(X,Y,Rect[GDX_Frames].MinX,Rect[GDX_Frames].MinY,
Rect[GDX_Frames].MaxX,Rect[GDX_Frames].MaxY))
HNum = H_Frames;
else
if (PointInBox(X,Y,Rect[GDX_Start].MinX,Rect[GDX_Start].MinY,
Rect[GDX_Start].MaxX,Rect[GDX_Start].MaxY))
HNum = H_Start;
else
if (PointInBox(X,Y,Rect[GDX_Name].MinX,Rect[GDX_Name].MinY,
Rect[GDX_Name].MaxX,Rect[GDX_Name].MaxY))
HNum = H_Name;
else
// following should use the gadget sizing stuff - doubt if anybody will notice
if (PointInBox(X,Y,0,0,
20,TSMorphWnd->BorderTop))
HNum = H_IClose;
else
if (PointInBox(X,Y,(TSMorphWnd->Width - 24),0,
TSMorphWnd->Width,TSMorphWnd->BorderTop))
HNum = H_IDepth;
else
if (PointInBox(X,Y,(TSMorphWnd->Width - 24 - 24),0,
(TSMorphWnd->Width - 24),TSMorphWnd->BorderTop))
HNum = H_IZoom;
else
HNum = H_IWindow;
help(HNum);
break;
}
return 1;
}
/* Handle Vanilla Key in Information
* Window - from GadToolsBox
*/
int
TSMorphVanillaKey(void) {
switch (TSMorphMsg.Code) {
case 'o':
case 'O':
/* O - if control window not open
* either activate string gadget
* or display file requester with shift
*/
if (!ControlWindow) {
if (TSMorphMsg.Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)) {
GetFileOneClicked();
}
else {
ActivateGadget(TSMorphGadgets[GDX_FileOne],TSMorphWnd,NULL);
}
}
break;
case 't':
case 'T':
/* T - if control window not open
* either activate string gadget
* or display file requester with shift
*/
if (!ControlWindow) {
if (TSMorphMsg.Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)) {
GetFileTwoClicked();
}
else {
ActivateGadget(TSMorphGadgets[GDX_FileTwo],TSMorphWnd,NULL);
}
}
break;
case '1':
case '!':
/* 1 - either activate string gadget
* or display file requester with shift
*/
if (TSMorphMsg.Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)) {
GetFile1Clicked();
}
else {
ActivateGadget(TSMorphGadgets[GDX_File241],TSMorphWnd,NULL);
}
break;
case '2':
case '"':
/* 2 - either activate string gadget
* or display file requester with shift
*/
if (TSMorphMsg.Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)) {
GetFile2Clicked();
}
else {
ActivateGadget(TSMorphGadgets[GDX_File242],TSMorphWnd,NULL);
}
break;
case 'r':
case 'R':
// R - Cycle Single
if (!ControlWindow) {
if (TSMorphMsg.Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)) {
if (!SinglePicture) {
// If we do not have reqtools then do not allow Anims
if (ReqToolsBase) {
SinglePicture = 3;
}
else {
SinglePicture = 1;
}
}
else {
--SinglePicture;
}
}
else {
if (ReqToolsBase) {
// If we do not have reqtools then do not allow Anims
if (SinglePicture == 3) {
SinglePicture = 0;
}
else {
++SinglePicture;
}
}
else {
if (SinglePicture == 1) {
SinglePicture = 0;
}
else {
++SinglePicture;
}
}
}
Saved = FALSE;
GT_SetGadgetAttrs(TSMorphGadgets[GDX_SinglePicture],TSMorphWnd,NULL,
GTCY_Active,SinglePicture, TAG_END );
}
break;
case 'f':
case 'F':
// F - activate string gadgtet
if (!ControlWindow) {
ActivateGadget(TSMorphGadgets[GDX_Frames],TSMorphWnd,NULL);
}
break;
case 'a':
case 'A':
// A - activate string gadgtet
if (!ControlWindow) {
ActivateGadget(TSMorphGadgets[GDX_Start],TSMorphWnd,NULL);
}
break;
case 'n':
case 'N':
/* N - either activate string gadget
* or display file requester with shift
*/
if (TSMorphMsg.Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)) {
GetSaveNameClicked();
}
else {
ActivateGadget(TSMorphGadgets[GDX_Name],TSMorphWnd,NULL);
}
break;
case 'p':
case 'P':
/* P - either open Control and image windows
* or activate and bring control window to front
*/
if (!ControlWindow) {
OpenPointsEdit();
}
else {
ActivateWindow(ControlWindow);
WindowToFront(ControlWindow);
}
break;
default:
// other key
break;
}
return 1;
}
/* Open... menu item in Info window */
int
TSMorphMenuOpen(void) {
// Just call MyOpen();
DisableWindows(DI_WaitOpen);
MyOpen(NULL,FALSE,TRUE);
EnableWindows();
return 1;
}
/* Save menu item in Info window */
int TSMorphMenuSave(void) {
// Just call SaveAs(last saved name)
DisableWindows(DI_WaitSave);
SaveAs(savedfilename);
EnableWindows();
return 1;
}
/* Save As... menu item in Info window */
int
TSMorphMenuSaveAs(void) {
// Just call SaveAs(no name)
DisableWindows(DI_WaitSave);
SaveAs(NULL);
EnableWindows();
return 1;
}
/* Delete... menu item in Info window */
int
TSMorphMenuDelete(void) {
BPTR cd;
BOOL ok = TRUE;
struct AnchorPath ap = {0};
// Delete a project with Icon and all .nnn files
DisableWindows(DI_Delete);
if (GetAFile("","TSMorph - Delete Project",FILF_SAVE)) {
// delete main file and icon
DeleteFile(TempFilename);
DeleteDiskObject(TempFilename);
// delete "project.nnn" files
strcat(TempFilename,".[0-9][0-9][0-9]");
if (!MatchFirst(TempFilename,&ap)) {
while (ok) {
cd = CurrentDir(ap.ap_Current->an_Lock);
DeleteFile(ap.ap_Info.fib_FileName);
CurrentDir(cd);
ok = !MatchNext(&ap);
}
}
MatchEnd(&ap);
}
EnableWindows();
return 1;
}
/* About menu item in Info window */
int
TSMorphMenuAbout(void) {
// Just Call About()
DisableWindows(DI_About);
About();
EnableWindows();
return 1;
}
/* Quit menu item in Info window */
int
TSMorphMenuQuit(void) {
// Suggest save - quit if requested
if (!Saved) {
return !SaveRequester();
}
else {
return 0;
}
}
/* Edit Points... menu item in Info window */
int
TSMorphMenuEditPoints(void) {
// Open window if not open
if (!ControlWindow) {
OpenPointsEdit();
}
// Otherwise activate and bring to front
else {
ActivateWindow(ControlWindow);
WindowToFront(ControlWindow);
}
return 1;
}
/* Window closed, acts like quit */
int TSMorphCloseWindow(void) {
// Suggest save - quit if required
if (!Saved) {
return !SaveRequester();
}
else {
return 0;
}
}
/* Help pressed on a menu in the info window */
int
TSMorphMenuHelp(void) {
ULONG HNum; // Help node
// Forget any previous changes
// This means all menu selections before help is pressed are ignored
RemoveMenus();
SwitchMenuItem(MM_PALETTE,palette,FALSE);
SwitchMenuItem(MM_ZOOM,Zoom,FALSE);
SwitchMenuItem(MM_ICONSP,CreateIconsP,FALSE);
UpdateOpenMode(FALSE);
SwitchMenuItem(MM_ICONSR,CreateIconsR,FALSE);
UpdateRenderMode(FALSE);
UpdateSaveFormat(FALSE);
AddMenus();
// Determine help number from menu position
switch (TSMorphMsg.Code) {
case FULLMENUNUM(0,NOITEM,NOSUB):
case FULLMENUNUM(0,2,NOSUB):
case FULLMENUNUM(0,6,NOSUB):
case FULLMENUNUM(0,8,NOSUB):
case FULLMENUNUM(0,10,NOSUB):
HNum = H_IMP;
break;
case FULLMENUNUM(0,0,NOSUB):
HNum = H_IMPN;
break;
case FULLMENUNUM(0,1,NOSUB):
HNum = H_IMPO;
break;
case FULLMENUNUM(0,3,NOSUB):
HNum = H_IMPS;
break;
case FULLMENUNUM(0,4,NOSUB):
HNum = H_IMPSA;
break;
case FULLMENUNUM(0,5,NOSUB):
HNum = H_IMPD;
break;
case FULLMENUNUM(0,7,NOSUB):
HNum = H_IMPA;
break;
case FULLMENUNUM(0,9,NOSUB):
HNum = H_IMPQ;
break;
case FULLMENUNUM(0,11,NOSUB):
HNum = H_IMPP;
break;
case FULLMENUNUM(0,12,NOSUB):
HNum = H_IMPE;
break;
case FULLMENUNUM(1,NOITEM,NOSUB):
case FULLMENUNUM(1,MM_C1,NOSUB):
case FULLMENUNUM(1,MM_C2,NOSUB):
case FULLMENUNUM(1,MM_C3,NOSUB):
case FULLMENUNUM(1,MM_C4,NOSUB):
HNum = H_IMS;
break;
case FULLMENUNUM(1,MM_ICONS,NOSUB):
HNum = H_P_CI;
break;
case FULLMENUNUM(1,MM_PALETTE,NOSUB):
HNum = H_P_CP;
break;
case FULLMENUNUM(1,MM_ZOOM,NOSUB):
HNum = H_P_ZO;
break;
case FULLMENUNUM(1,MM_OPENMODE,NOSUB):
case FULLMENUNUM(1,MM_OPENMODE,MI_ALWAYS):
case FULLMENUNUM(1,MM_OPENMODE,MI_IFILBM):
case FULLMENUNUM(1,MM_OPENMODE,MI_IFCOLOURS):
case FULLMENUNUM(1,MM_OPENMODE,MI_REMAP):
case FULLMENUNUM(1,MM_OPENMODE,MI_OPAL):
HNum = H_P_OM;
break;
case FULLMENUNUM(1,MM_SCREEN,NOSUB):
HNum = H_P_PS;
break;
case FULLMENUNUM(1,MM_CUSTOM,NOSUB):
HNum = H_PCUSTM;
break;
case FULLMENUNUM(1,MM_CDEPTH,NOSUB):
HNum = H_PCUSTD;
break;
case FULLMENUNUM(1,MM_SPREVIEW,NOSUB):
HNum = H_P_Preview;
break;
case FULLMENUNUM(1,MM_ICONSP,NOSUB):
HNum = H_P_CIP;
break;
case FULLMENUNUM(1,MM_KEEPS,NOSUB):
HNum = H_P_KS;
break;
case FULLMENUNUM(1,MM_LOADS,NOSUB):
HNum = H_P_LOADS;
break;
case FULLMENUNUM(1,MM_SAVES,NOSUB):
HNum = H_P_SAVES;
break;
case FULLMENUNUM(1,MM_SAVESAS,NOSUB):
HNum = H_P_SAVESAS;
break;
case FULLMENUNUM(1,MM_ICONSR,NOSUB):
HNum = H_P_CIR;
break;
case FULLMENUNUM(1,MM_DX,NOSUB):
HNum = H_P_DX;
break;
case FULLMENUNUM(1,MM_DY,NOSUB):
HNum = H_P_DY;
break;
case FULLMENUNUM(1,MM_LOADSCRIPT,NOSUB):
HNum = H_P_LS;
break;
case FULLMENUNUM(1,MM_PRESCRIPT,NOSUB):
HNum = H_P_PES;
break;
case FULLMENUNUM(1,MM_POSTSCRIPT,NOSUB):
HNum = H_P_POS;
break;
case FULLMENUNUM(1,MM_DEPTH,NOSUB):
HNum = H_P_DE;
break;
case FULLMENUNUM(1,MM_RENDERMODE,NOSUB):
case FULLMENUNUM(1,MM_RENDERMODE,MI_MODE0):
case FULLMENUNUM(1,MM_RENDERMODE,MI_MODE1):
case FULLMENUNUM(1,MM_RENDERMODE,MI_MODE2):
case FULLMENUNUM(1,MM_RENDERMODE,MI_MODE3):
HNum = H_P_MO;
break;
case FULLMENUNUM(1,MM_SAVEFORMAT,NOSUB):
case FULLMENUNUM(1,MM_SAVEFORMAT,MI_ILBM24):
case FULLMENUNUM(1,MM_SAVEFORMAT,MI_OPAL24):
case FULLMENUNUM(1,MM_SAVEFORMAT,MI_OPAL24T):
case FULLMENUNUM(1,MM_SAVEFORMAT,MI_OPAL24F):
case FULLMENUNUM(1,MM_SAVEFORMAT,MI_OPAL24FT):
case FULLMENUNUM(1,MM_SAVEFORMAT,MI_JPEG):
case FULLMENUNUM(1,MM_SAVEFORMAT,MI_JPEGT):
case FULLMENUNUM(1,MM_SAVEFORMAT,MI_PBM):
case FULLMENUNUM(1,MM_SAVEFORMAT,MI_BW16):
case FULLMENUNUM(1,MM_SAVEFORMAT,MI_BW256):
case FULLMENUNUM(1,MM_SAVEFORMAT,MI_HAM6):
case FULLMENUNUM(1,MM_SAVEFORMAT,MI_HAM8):
case FULLMENUNUM(1,MM_SAVEFORMAT,MI_DCTV3):
case FULLMENUNUM(1,MM_SAVEFORMAT,MI_DCTV4):
HNum = H_P_SF;
break;
case FULLMENUNUM(1,MM_QUALITY,NOSUB):
HNum = H_P_QU;
break;
case FULLMENUNUM(1,MM_SCREENR,NOSUB):
HNum = H_P_PSR;
break;
case FULLMENUNUM(1,MM_ANTIALIAS,NOSUB):
HNum = H_P_AA;
break;
case FULLMENUNUM(1,MM_RESETD,NOSUB):
HNum = H_S_RD;
break;
case FULLMENUNUM(1,MM_LASTS,NOSUB):
HNum = H_S_LS;
break;
case FULLMENUNUM(1,MM_RESTORE,NOSUB):
HNum = H_S_R;
break;
case FULLMENUNUM(1,MM_HELP,NOSUB):
HNum = H_P_HE;
break;
case MENUNULL:
default:
HNum = H_IM;
break;
}
// Display help
help(HNum);
return 1;
}
/* String gadget clicked */
int
File241Clicked(void) {
// Only read when required - display help if help pressed
if (TSMorphMsg.Code == 0x5F) {
help(H_24File1);
}
Saved = FALSE;
return 1;
}
/* String gadget clicked */
int
File242Clicked(void) {
// Only read when required - display help if help pressed
if (TSMorphMsg.Code == 0x5F) {
help(H_24File2);
}
Saved = FALSE;
return 1;
}
/* String gadget clicked */
int
FramesClicked(void) {
// Only read when required - display help if help pressed
if (TSMorphMsg.Code == 0x5F) {
help(H_Frames);
}
Saved = FALSE;
return 1;
}
/* String gadget clicked */
int
FileOneClicked(void) {
// Only read when required - display help if help pressed
if (TSMorphMsg.Code == 0x5F) {
help(H_FileOne);
}
Saved = FALSE;
return 1;
}
/* String gadget clicked */
int FileTwoClicked(void) {
// Only read when required - display help if help pressed
if (TSMorphMsg.Code == 0x5F) {
help(H_FileTwo);
}
Saved = FALSE;
return 1;
}
/* CheckBox clicked */
int
SinglePictureClicked(void) {
// Toggle BOOL
SinglePicture = TSMorphMsg.Code;
Saved = FALSE;
return 1;
}
/* String gadget clicked */
int
NameClicked(void) {
// Only read when required - display help if help pressed
if (TSMorphMsg.Code == 0x5F) {
help(H_Name);
}
Saved = FALSE;
return 1;
}
/* String gadget clicked */
int
StartClicked(void) {
// Read when required - display help if help pressed
if (TSMorphMsg.Code == 0x5F) {
help(H_Start);
}
Saved = FALSE;
return 1;
}
/* Edit Points gadget clicked */
int
EditPointsClicked(void) {
// Open window if not open
if (!ControlWindow) {
OpenPointsEdit();
}
// Otherwise activate and bring to front
else {
ActivateWindow(ControlWindow);
WindowToFront(ControlWindow);
}
return 1;
}
/* Open the Control and Image Windows */
void
OpenPointsEdit(void) {
char buffer[257];
BOOL ok=TRUE;
// Open Control window, Pic1 and Pic2
if ((SinglePicture == 2) || (SinglePicture == 3)) { // Anim so need frame number
ok = GetFrameNumber();
}
if (ok) {
if (ControlWindow = OpenControlWindow()) { // note multiple calls to DisableWindows()
DisableWindows(DI_Image1); // are safe, required to disable just opened window
Pic1_Open = openAPicture(GetString(TSMorphGadgets[GDX_FileOne]),&Pic1,TRUE);
if (Pic1_Open) {
DisableWindows(DI_Image2);
Pic2_Open = openAPicture(GetString(TSMorphGadgets[GDX_FileTwo]),&Pic2,TRUE);
if (Pic2_Open) {
DisableWindows(DI_Draw);
// validate image sizes
if ((Pic1.ilbm->Bmhd.w != Pic2.ilbm->Bmhd.w) ||
(Pic1.ilbm->Bmhd.h != Pic2.ilbm->Bmhd.h)) {
Error("Both Images must be the same size","OK",NULL,HE_Size);
CloseAPicture(&Pic2);
Pic2_Open = FALSE;
CloseAPicture(&Pic1);
Pic1_Open = FALSE;
}
else {
// if we have changed from non anim to anim then we may still have
// points in memory - so draw, otherwise try and load points file
if ((!(((struct MyPoint *)PointList.lh_Head)->MyNode.mln_Succ)) &&
((SinglePicture == 2) || (SinglePicture == 3))) {
strcpy(TempFilename,savedfilename);
strcat(TempFilename,".%03ld");
sprintf(buffer,TempFilename,FrameNumber);
MyOpen(buffer,TRUE,FALSE);
}
else {
DrawAllPoints();
}
// disable some menus, generally set up and activate things
SetMyPointer();
EnableWindows();
OffMenu(TSMorphWnd,FULLMENUNUM(0,0,NOSUB));
OffMenu(TSMorphWnd,FULLMENUNUM(0,1,NOSUB));
ActivateWindow(ControlWindow);
return;
}
}
// Tidy up and close down cleanly
else {
CloseAPicture(&Pic1);
Pic1_Open = FALSE;
}
}
CloseControlWindow();
}
EnableWindows();
}
}
/* Display ASL requesters */
int
GetFile1Clicked(void) {
if (GetAFile(GetString(TSMorphGadgets[GDX_File241]),"TSMorph - 24 bit pic 1",0)) {
GT_SetGadgetAttrs(TSMorphGadgets[GDX_File241],TSMorphWnd,NULL,
GTST_String, TempFilename, TAG_END );
Saved = FALSE;
}
return 1;
}
/* Display ASL requesters */
int
GetFile2Clicked(void) {
if (GetAFile(GetString(TSMorphGadgets[GDX_File242]),"TSMorph - 24 bit pic 2",0)) {
GT_SetGadgetAttrs(TSMorphGadgets[GDX_File242],TSMorphWnd,NULL,
GTST_String, TempFilename, TAG_END );
Saved = FALSE;
}
return 1;
}
/* Display ASL requesters */
int
GetFileOneClicked(void) {
if (!ControlWindow) {
if (GetAFile(GetString(TSMorphGadgets[GDX_FileOne]),"TSMorph - pic 1",0)) {
GT_SetGadgetAttrs(TSMorphGadgets[GDX_FileOne],TSMorphWnd,NULL,
GTST_String, TempFilename, TAG_END );
Saved = FALSE;
}
}
return 1;
}
/* Display ASL requesters */
int
GetFileTwoClicked(void) {
if (!ControlWindow) {
if (GetAFile(GetString(TSMorphGadgets[GDX_FileTwo]),"TSMorph - pic 2",0)) {
GT_SetGadgetAttrs(TSMorphGadgets[GDX_FileTwo],TSMorphWnd,NULL,
GTST_String, TempFilename, TAG_END );
Saved = FALSE;
}
}
return 1;
}
/* Display ASL requesters */
int
GetSaveNameClicked(void) {
if (GetAFile(GetString(TSMorphGadgets[GDX_Name]),"TSMorph - Morph file name",0)) {
GT_SetGadgetAttrs(TSMorphGadgets[GDX_Name],TSMorphWnd,NULL,
GTST_String, TempFilename, TAG_END );
Saved = FALSE;
}
return 1;
}
/* Displays requester to add a grid of points */
void
AddGrid(void) {
int flag = 1;
// Open window and wait till close selected then close it
DisableWindows(DI_Grid);
if (!OpenGridRequestWindow()) {
while (flag) {
Wait((1L << GridRequestWnd->UserPort->mp_SigBit));
flag = HandleGridRequestIDCMP();
}
}
else {
Error("Unable to %s","OK","Open Grid Requester",HE_OGrid);
}
CloseGridRequestWindow();
EnableWindows();
}
/* Actually add the grid of points */
void
ReallyAddGrid(void) {
UWORD xgrid; // Number horizontally
UWORD ygrid; // Number vertically
UWORD x; // X coord
UWORD y; // Y coord
BOOL ok = TRUE;// Is it working?
struct MyPoint **MyPointp; // Point Pointer
struct MyPoint *MyPoint; // Point
// Read X and Y numbers
xgrid = GetNumber(GridRequestGadgets[GDX_XCells]);
ygrid = GetNumber(GridRequestGadgets[GDX_YCells]);
if (xgrid && ygrid) {
/* Allocate Pointer to points memory
* We need an array but cannot allocate all points
* as one block of memory as a single point can be deleted
*/
if (MyPointp = AllocMem(sizeof(struct MyPoint *)*((xgrid+1)*(ygrid+1)),MEMF_CLEAR)) {
// Create and draw all points
for (x = 0;
ok && (x <= xgrid);
++x) {
for (y = 0;
ok && (y <= ygrid);
++y) {
if (MyPoint = MyPointp[x*(xgrid+1)+y] = AllocMem(sizeof(struct MyPoint),MEMF_CLEAR)) {
Saved = FALSE;
MyPoint->x = (x * (Width-1))/xgrid;
MyPoint->y = (y * (Height-1))/ygrid;
MyPoint->x1 = MyPoint->x;
MyPoint->y1 = MyPoint->y;
AddTail(&PointList,(struct Node *)MyPoint);
DrawPixels(&Pic1,MyPoint->x,MyPoint->y,MyPoint);
DrawPixels(&Pic2,MyPoint->x1,MyPoint->y1,MyPoint);
}
else {
ok = FALSE;
}
}
}
if (ok) {
// Link all points - link top left to bottom right
for (x = 0;
x <= xgrid;
++x) {
for (y = 0;
y <= ygrid;
++y) {
if (x < xgrid) {
LinkPoints(MyPointp[x*(xgrid+1)+y],MyPointp[(x+1)*(xgrid+1)+y]);
}
if (y < ygrid) {
LinkPoints(MyPointp[x*(xgrid+1)+y],MyPointp[x*(xgrid+1)+y+1]);
}
}
}
}
// Free the Points pointers
FreeMem(MyPointp,sizeof(struct MyPoint *)*((xgrid+1)*(ygrid+1)));
}
else {
ok = FALSE;
}
}
else {
Error("Both X Cells and Y Cells must be > 0","OK",NULL,HE_Grid0);
}
if (!ok) {
Error("Out of memory for points","OK",NULL,HE_MPoints);
}
}
/* Display help on a control or image window menu
* Code : menu code
* Note: this is a virtual clone of the code above (with 1 changed to M_SETTINGS)
*/
void
DoMenuHelp(USHORT Code) {
ULONG HNum; // Help node
/* Reset everything which could have been set
* using the menu
*/
RemoveMenus();
MySetMode(Mode);
// Forget any previous changes
SwitchMenuItem(MM_PALETTE,palette,FALSE);
SwitchMenuItem(MM_ZOOM,Zoom,FALSE);
SwitchMenuItem(MM_ICONSP,CreateIconsP,FALSE);
UpdateOpenMode(FALSE);
SwitchMenuItem(MM_ICONSR,CreateIconsR,FALSE);
UpdateRenderMode(FALSE);
UpdateSaveFormat(FALSE);
AddMenus();
// Determine help node
switch (Code) {
case FULLMENUNUM(M_PROJECT,NOITEM,NOSUB):
case FULLMENUNUM(M_PROJECT,MM_B1,NOSUB):
case FULLMENUNUM(M_PROJECT,MM_B2,NOSUB):
case FULLMENUNUM(M_PROJECT,MM_B3,NOSUB):
case FULLMENUNUM(M_PROJECT,MM_B4,NOSUB):
case FULLMENUNUM(M_PROJECT,MM_B5,NOSUB):
HNum = H_CMP;
break;
case FULLMENUNUM(M_PROJECT,MM_NEW,NOSUB):
HNum = H_CMPN;
break;
case FULLMENUNUM(M_PROJECT,MM_OPEN,NOSUB):
HNum = H_CMPO;
break;
case FULLMENUNUM(M_PROJECT,MM_SAVE,NOSUB):
HNum = H_CMPS;
break;
case FULLMENUNUM(M_PROJECT,MM_SAVEAS,NOSUB):
HNum = H_CMPSA;
break;
case FULLMENUNUM(M_PROJECT,MM_ABOUT,NOSUB):
HNum = H_CMPA;
break;
case FULLMENUNUM(M_PROJECT,MM_EXITPOINTS,NOSUB):
HNum = H_CMPE;
break;
case FULLMENUNUM(M_PROJECT,MM_QUIT,NOSUB):
HNum = H_CMPQ;
break;
case FULLMENUNUM(M_PROJECT,MM_PPREVIEW,NOSUB):
HNum = H_CMPP;
break;
case FULLMENUNUM(M_EDIT,NOITEM,NOSUB):
HNum = H_CME;
break;
case FULLMENUNUM(M_EDIT,MM_GRID,NOSUB):
HNum = H_CMEG;
break;
case FULLMENUNUM(M_EDIT,MM_FRAME,NOSUB):
HNum = H_CMEF;
break;
case FULLMENUNUM(M_EDIT,MM_FRAME,MI_FIRST):
HNum = H_CMEFF;
break;
case FULLMENUNUM(M_EDIT,MM_FRAME,MI_PREV):
HNum = H_CMEFP;
break;
case FULLMENUNUM(M_EDIT,MM_FRAME,MI_GOTO):
HNum = H_CMEFG;
break;
case FULLMENUNUM(M_EDIT,MM_FRAME,MI_NEXT):
HNum = H_CMEFN;
break;
case FULLMENUNUM(M_EDIT,MM_FRAME,MI_LAST):
HNum = H_CMEFL;
break;
case FULLMENUNUM(M_EDIT,MM_MODE,NOSUB):
HNum = H_CMSM;
break;
case FULLMENUNUM(M_EDIT,MM_MODE,MI_EDITONE):
HNum = H_EOne;
break;
case FULLMENUNUM(M_EDIT,MM_MODE,MI_EDITTWO):
HNum = H_ETwo;
break;
case FULLMENUNUM(M_EDIT,MM_MODE,MI_EDITREL):
HNum = H_ERel;
break;
case FULLMENUNUM(M_EDIT,MM_MODE,MI_ADD):
HNum = H_EAdd;
break;
case FULLMENUNUM(M_EDIT,MM_MODE,MI_DELETE):
HNum = H_EDel;
break;
case FULLMENUNUM(M_EDIT,MM_MODE,MI_LINK):
HNum = H_ELnk;
break;
case FULLMENUNUM(M_EDIT,MM_MODE,MI_UNLINK):
HNum = H_EUnl;
break;
case FULLMENUNUM(M_EDIT,MM_MODE,MI_NONE):
HNum = H_EMov;
break;
case FULLMENUNUM(M_SETTINGS,NOITEM,NOSUB):
case FULLMENUNUM(M_SETTINGS,MM_C1,NOSUB):
case FULLMENUNUM(M_SETTINGS,MM_C2,NOSUB):
case FULLMENUNUM(M_SETTINGS,MM_C3,NOSUB):
case FULLMENUNUM(M_SETTINGS,MM_C4,NOSUB):
HNum = H_IMS;
break;
case FULLMENUNUM(M_SETTINGS,MM_ICONS,NOSUB):
HNum = H_P_CI;
break;
case FULLMENUNUM(M_SETTINGS,MM_PALETTE,NOSUB):
HNum = H_P_CP;
break;
case FULLMENUNUM(M_SETTINGS,MM_ZOOM,NOSUB):
HNum = H_P_ZO;
break;
case FULLMENUNUM(M_SETTINGS,MM_OPENMODE,NOSUB):
case FULLMENUNUM(M_SETTINGS,MM_OPENMODE,MI_ALWAYS):
case FULLMENUNUM(M_SETTINGS,MM_OPENMODE,MI_IFILBM):
case FULLMENUNUM(M_SETTINGS,MM_OPENMODE,MI_IFCOLOURS):
case FULLMENUNUM(M_SETTINGS,MM_OPENMODE,MI_REMAP):
case FULLMENUNUM(M_SETTINGS,MM_OPENMODE,MI_OPAL):
HNum = H_P_OM;
break;
case FULLMENUNUM(M_SETTINGS,MM_SCREEN,NOSUB):
HNum = H_P_PS;
break;
case FULLMENUNUM(M_SETTINGS,MM_CUSTOM,NOSUB):
HNum = H_PCUSTM;
break;
case FULLMENUNUM(M_SETTINGS,MM_CDEPTH,NOSUB):
HNum = H_PCUSTD;
break;
case FULLMENUNUM(M_SETTINGS,MM_SPREVIEW,NOSUB):
HNum = H_P_Preview;
break;
case FULLMENUNUM(M_SETTINGS,MM_ICONSP,NOSUB):
HNum = H_P_CIP;
break;
case FULLMENUNUM(M_SETTINGS,MM_KEEPS,NOSUB):
HNum = H_P_KS;
break;
case FULLMENUNUM(M_SETTINGS,MM_LOADS,NOSUB):
HNum = H_P_LOADS;
break;
case FULLMENUNUM(M_SETTINGS,MM_SAVES,NOSUB):
HNum = H_P_SAVES;
break;
case FULLMENUNUM(M_SETTINGS,MM_SAVESAS,NOSUB):
HNum = H_P_SAVESAS;
break;
case FULLMENUNUM(M_SETTINGS,MM_ICONSR,NOSUB):
HNum = H_P_CIR;
break;
case FULLMENUNUM(M_SETTINGS,MM_DX,NOSUB):
HNum = H_P_DX;
break;
case FULLMENUNUM(M_SETTINGS,MM_DY,NOSUB):
HNum = H_P_DY;
break;
case FULLMENUNUM(M_SETTINGS,MM_LOADSCRIPT,NOSUB):
HNum = H_P_LS;
break;
case FULLMENUNUM(M_SETTINGS,MM_PRESCRIPT,NOSUB):
HNum = H_P_PES;
break;
case FULLMENUNUM(M_SETTINGS,MM_POSTSCRIPT,NOSUB):
HNum = H_P_POS;
break;
case FULLMENUNUM(M_SETTINGS,MM_DEPTH,NOSUB):
HNum = H_P_DE;
break;
case FULLMENUNUM(M_SETTINGS,MM_RENDERMODE,NOSUB):
case FULLMENUNUM(M_SETTINGS,MM_RENDERMODE,MI_MODE0):
case FULLMENUNUM(M_SETTINGS,MM_RENDERMODE,MI_MODE1):
case FULLMENUNUM(M_SETTINGS,MM_RENDERMODE,MI_MODE2):
case FULLMENUNUM(M_SETTINGS,MM_RENDERMODE,MI_MODE3):
HNum = H_P_MO;
break;
case FULLMENUNUM(M_SETTINGS,MM_SAVEFORMAT,NOSUB):
case FULLMENUNUM(M_SETTINGS,MM_SAVEFORMAT,MI_ILBM24):
case FULLMENUNUM(M_SETTINGS,MM_SAVEFORMAT,MI_OPAL24):
case FULLMENUNUM(M_SETTINGS,MM_SAVEFORMAT,MI_OPAL24T):
case FULLMENUNUM(M_SETTINGS,MM_SAVEFORMAT,MI_OPAL24F):
case FULLMENUNUM(M_SETTINGS,MM_SAVEFORMAT,MI_OPAL24FT):
case FULLMENUNUM(M_SETTINGS,MM_SAVEFORMAT,MI_JPEG):
case FULLMENUNUM(M_SETTINGS,MM_SAVEFORMAT,MI_JPEGT):
case FULLMENUNUM(M_SETTINGS,MM_SAVEFORMAT,MI_PBM):
case FULLMENUNUM(M_SETTINGS,MM_SAVEFORMAT,MI_BW16):
case FULLMENUNUM(M_SETTINGS,MM_SAVEFORMAT,MI_BW256):
case FULLMENUNUM(M_SETTINGS,MM_SAVEFORMAT,MI_HAM6):
case FULLMENUNUM(M_SETTINGS,MM_SAVEFORMAT,MI_HAM8):
case FULLMENUNUM(M_SETTINGS,MM_SAVEFORMAT,MI_DCTV3):
case FULLMENUNUM(M_SETTINGS,MM_SAVEFORMAT,MI_DCTV4):
HNum = H_P_SF;
break;
case FULLMENUNUM(M_SETTINGS,MM_QUALITY,NOSUB):
HNum = H_P_QU;
break;
case FULLMENUNUM(M_SETTINGS,MM_SCREENR,NOSUB):
HNum = H_P_PSR;
break;
case FULLMENUNUM(M_SETTINGS,MM_ANTIALIAS,NOSUB):
HNum = H_P_AA;
break;
case FULLMENUNUM(M_SETTINGS,MM_RESETD,NOSUB):
HNum = H_S_RD;
break;
case FULLMENUNUM(M_SETTINGS,MM_LASTS,NOSUB):
HNum = H_S_LS;
break;
case FULLMENUNUM(M_SETTINGS,MM_RESTORE,NOSUB):
HNum = H_S_R;
break;
case FULLMENUNUM(M_SETTINGS,MM_HELP,NOSUB):
HNum = H_P_HE;
break;
case MENUNULL:
default:
HNum = H_CM;
break;
}
help(HNum);
}
/* String gadget clicked */
int
XCellsClicked(void) {
// Display help if required
if (GridRequestMsg.Code == 0x5F) {
help(H_RAGGX);
}
return 1;
}
/* String gadget clicked */
int
YCellsClicked(void) {
// Display help if required
if (GridRequestMsg.Code == 0x5F) {
help(H_RAGGY);
}
return 1;
}
/* OK gadget clicked so add the grid */
int
OKClicked(void) {
ReallyAddGrid();
return 0;
}
/* Cancel clicked - do not add grid */
int
CancelClicked(void) {
return 0;
}
/* Close Window - do not add grid */
int
GridRequestCloseWindow(void) {
return 0;
}
/* Vanilla Key in Add Grid */
int
GridRequestVanillaKey(void) {
switch (GridRequestMsg.Code) {
case 'o':
case 'O':
// Same as OK
OKClicked();
return 0;
break;
case 'x':
case 'X':
// Activate string gadget
ActivateGadget(GridRequestGadgets[GDX_XCells],GridRequestWnd,NULL);
break;
case 'y':
case 'Y':
// Activate string gadget
ActivateGadget(GridRequestGadgets[GDX_YCells],GridRequestWnd,NULL);
break;
case 'c':
case 'C':
// Cancel
return 0;
break;
}
return 1;
}
/* Raw key - Only help does anything */
int
GridRequestRawKey(void) {
UWORD X,Y; // Mouse coords
ULONG HNum; // Help node
X = GridRequestWnd->MouseX;
Y = GridRequestWnd->MouseY;
switch (GridRequestMsg.Code) {
case 0x5f:
// Help key - determine gadget or whole window
if (PointInBox(X,Y,GRect[GDX_XCells].MinX,GRect[GDX_XCells].MinY,
GRect[GDX_XCells].MaxX,GRect[GDX_XCells].MaxY))
HNum = H_RAGGX;
else
if (PointInBox(X,Y,GRect[GDX_YCells].MinX,GRect[GDX_YCells].MinY,
GRect[GDX_YCells].MaxX,GRect[GDX_YCells].MaxY))
HNum = H_RAGGY;
else
if (PointInBox(X,Y,GRect[GDX_OK].MinX,GRect[GDX_OK].MinY,
GRect[GDX_OK].MaxX,GRect[GDX_OK].MaxY))
HNum = H_RAGGOK;
else
if (PointInBox(X,Y,GRect[GDX_Cancel].MinX,GRect[GDX_Cancel].MinY,
GRect[GDX_Cancel].MaxX,GRect[GDX_Cancel].MaxY))
HNum = H_RAGGCA;
else
// should really use dynamic gadget size stuff
if (PointInBox(X,Y,0,0,
20,GridRequestWnd->BorderTop))
HNum = H_RAGGCL;
else
if (PointInBox(X,Y,(GridRequestWnd->Width - 24),0,
GridRequestWnd->Width,GridRequestWnd->BorderTop))
HNum = H_RAGGDE;
else
HNum = H_RAG;
help(HNum);
break;
}
return 1;
}
/* If project not saved then
* display requester and then
* save if required
* Returns: TRUE keep going
*/
BOOL
SaveRequester(void) {
struct EasyStruct EasyStruct = {
sizeof(struct EasyStruct),
0,
NULL,
NULL,
NULL
};
UBYTE *title = "TSMorph";
UBYTE *body = "Unsaved project\n%s";
UBYTE *gadget;
struct Window *req;
LONG gad=-1;
ULONG ret = 2;
ULONG signals;
struct rtHandlerInfo *rth;
struct AmigaGuideMsg *agm;
BOOL ret1;
char *other = &(savedfilename[0]);
// Disable the windows and display the requester - using reqtools if available
DisableWindows(DI_Unsaved);
if (ReqToolsBase) {
// set up gadgets depending on availability of amigaguide
if (handle) {
gadget = "_Save|_Help|_Abandon|_Cancel";
}
else {
gadget = "_Save|_Abandon|_Cancel";
}
// Loop until Save,Abandon or Cancel pressed
while (((ret == 2) && handle) || (gad == -1)) {
ret = CALL_HANDLER;
if (rtEZRequestTags(body,gadget,NULL,&other,
RT_ReqHandler, &rth,
RT_Window, TSMorphWnd,
RT_Underscore, '_',
RTEZ_ReqTitle, title,
TAG_END) == CALL_HANDLER) {
while (ret == CALL_HANDLER) {
if (!rth->DoNotWait) {
signals = Wait(rth->WaitMask | ASig);
}
ret = rtReqHandlerA(rth,signals,NULL);
if ((ret == 2) && handle) {
help(H_Unsaved);
}
if (signals & ASig) {
while (agm = GetAmigaGuideMsg(handle)) {
ReplyAmigaGuideMsg(agm);
}
}
}
}
else {
ret = 0;
}
gad = ret;
}
}
else {
EasyStruct.es_TextFormat = body;
EasyStruct.es_Title = title;
// set up gadgets depending on availability of amigaguide
if (handle) {
EasyStruct.es_GadgetFormat = "Save|Help|Abandon|Cancel";
}
else {
EasyStruct.es_GadgetFormat = "Save|Abandon|Cancel";
}
req = BuildEasyRequest(TSMorphWnd,&EasyStruct,NULL,savedfilename);
// Loop until Save,Abandon or Cancel pressed
while ((((gad = SysReqHandler(req,NULL,TRUE)) == 2) && handle) ||
(gad == -1)) {
if (handle) {
help(H_Unsaved);
}
}
FreeSysRequest(req);
}
switch(gad) {
case 1:
if (*savedfilename) {
ret1 = SaveAs(savedfilename);
}
else {
ret1 = SaveAs(NULL);
}
break;
case 2:
case 3: // 2 if no help, 3 otherwise
ret1 = TRUE;
break;
case 0:
ret1 = FALSE;
break;
}
EnableWindows();
return ret1;
}
/* Link two points
* Drawing in the windows if open
*/
void
LinkPoints(struct MyPoint* MyPoint,struct MyPoint *MyPoint1) {
// Link in first free position
if (!MyPoint->p1) {
MyPoint->p1 = MyPoint1;
}
else {
if (!MyPoint->p2) {
MyPoint->p2 = MyPoint1;
}
else {
if (!MyPoint->p3) {
MyPoint->p3 = MyPoint1;
}
else {
if (!MyPoint->p4) {
MyPoint->p4 = MyPoint1;
}
}
}
}
// Same the other way
if (!MyPoint1->p1) {
MyPoint1->p1 = MyPoint;
}
else {
if (!MyPoint1->p2) {
MyPoint1->p2 = MyPoint;
}
else {
if (!MyPoint1->p3) {
MyPoint1->p3 = MyPoint;
}
else {
if (!MyPoint1->p4) {
MyPoint1->p4 = MyPoint;
}
}
}
}
// If windows open then draw points and lines
if (Pic1_Open) {
MyDraw(Pic1.Win->RPort,MyPoint1->x<<Zoom,MyPoint1->y<<Zoom,MyPoint->x<<Zoom,MyPoint->y<<Zoom);
}
if (Pic2_Open) {
MyDraw(Pic2.Win->RPort,MyPoint1->x1<<Zoom,MyPoint1->y1<<Zoom,MyPoint->x1<<Zoom,MyPoint->y1<<Zoom);
}
}
/* Unlink two points
* Drawing on the screen if required
*/
void
UnlinkPoints(struct MyPoint* MyPoint,struct MyPoint *MyPoint1,BOOL MYDraw) {
// Erase lines if required
if (MYDraw) {
MyDraw(Pic1.Win->RPort,MyPoint1->x<<Zoom,MyPoint1->y<<Zoom,MyPoint->x<<Zoom,MyPoint->y<<Zoom);
MyDraw(Pic2.Win->RPort,MyPoint1->x1<<Zoom,MyPoint1->y1<<Zoom,MyPoint->x1<<Zoom,MyPoint->y1<<Zoom);
}
// Unlink each way
if (MyPoint->p1 == MyPoint1) {
MyPoint->p1 = NULL;
}
if (MyPoint->p2 == MyPoint1) {
MyPoint->p2 = NULL;
}
if (MyPoint->p3 == MyPoint1) {
MyPoint->p3 = NULL;
}
if (MyPoint->p4 == MyPoint1) {
MyPoint->p4 = NULL;
}
if (MyPoint1->p1 == MyPoint) {
MyPoint1->p1 = NULL;
}
if (MyPoint1->p2 == MyPoint) {
MyPoint1->p2 = NULL;
}
if (MyPoint1->p3 == MyPoint) {
MyPoint1->p3 = NULL;
}
if (MyPoint1->p4 == MyPoint) {
MyPoint1->p4 = NULL;
}
}
/* Find a point in an image given
* x and y coordinates
* Returns : NULL if none closeby
*/
struct MyPoint *
FindPoint(struct Picture *pic,WORD x,WORD y) {
struct MyPoint *MyPoint; // Point to look at
LONG diff = 36; // Must be closer than sqrt(36) pixels
LONG diff1; // sqr(distance apart) for current point
struct MyPoint *RetPoint = NULL; // Point being returned
// adjust coords for zoom and scroll
x+=(pic->Left>>Zoom);
y+=(pic->Top>>Zoom);
// Step thru all points and find closest
for (MyPoint = (struct MyPoint *)PointList.lh_Head;
MyPoint->MyNode.mln_Succ;
MyPoint = (struct MyPoint *)MyPoint->MyNode.mln_Succ) {
if (pic == &Pic1) {
diff1 = ((MyPoint->x-x)*(MyPoint->x-x)+
(MyPoint->y-y)*(MyPoint->y-y));
}
else {
diff1 = ((MyPoint->x1-x)*(MyPoint->x1-x)+
(MyPoint->y1-y)*(MyPoint->y1-y));
}
if (diff1<diff) {
diff = diff1;
RetPoint = MyPoint;
}
}
return RetPoint;
}
/* Delete a point
* removing all links
*/
void
DeletePoint(struct MyPoint *MyPoint){
// Unlink any links
if (MyPoint->p1) {
UnlinkPoints(MyPoint,MyPoint->p1,FALSE);
}
if (MyPoint->p2) {
UnlinkPoints(MyPoint,MyPoint->p2,FALSE);
}
if (MyPoint->p3) {
UnlinkPoints(MyPoint,MyPoint->p3,FALSE);
}
if (MyPoint->p4) {
UnlinkPoints(MyPoint,MyPoint->p4,FALSE);
}
// remove from list and free memory
Remove((struct Node *)MyPoint);
FreeMem(MyPoint,sizeof(struct MyPoint));
}
/* Similar to Draw() but always draws top left to bottom right
* to prevent stray pixels if erasing by drawing in the other direction
*/
void
MyDraw(struct RastPort *rp, SHORT x, SHORT y, SHORT oldx, SHORT oldy) {
if ((oldx < x) || ((oldx == x) && (oldy < y))) {
Move(rp,oldx,oldy);
Draw(rp,x,y);
}
else {
Move(rp,x,y);
Draw(rp,oldx,oldy);
}
}
/* Shows ASL file requester for a file
* name : current file name
* Prompt: Title
* flags : e.g. for save flag
* Returns: TRUE if file selected, name is TempFileName
*/
BOOL
GetAFile(char *name,char *Prompt,ULONG flags) {
// Split of directory name
strncpy(TempFilename,name,PathPart(name) - name);
TempFilename[PathPart(name) - name] = 0;
// Show requesters
if (AslRequestTags((APTR) filereq,
ASL_Hail,(Tag) Prompt,
ASL_FuncFlags,flags,
ASL_Dir, (Tag) TempFilename,
ASL_File,(Tag) FilePart(name),
ASL_Window, TSMorphWnd,
TAG_DONE)) {
// rejoin name
strncpy(TempFilename,filereq->rf_Dir,256);
AddPart(TempFilename,filereq->rf_File,256);
return TRUE;
}
else {
return FALSE;
}
}
/* New selected on the Info window */
int
TSMorphMenuNew(void) {
// Suggest save if unsaved
if (!Saved) {
if (!SaveRequester()) {
return 1;
}
DisableWindows(DI_New);
}
// Reset everything
Saved = TRUE;
savedfilename[0]=0;
DeleteAllPoints();
GT_SetGadgetAttrs(TSMorphGadgets[GDX_FileOne],TSMorphWnd,NULL,
GTST_String, "", TAG_END );
GT_SetGadgetAttrs(TSMorphGadgets[GDX_FileTwo],TSMorphWnd,NULL,
GTST_String, "", TAG_END );
GT_SetGadgetAttrs(TSMorphGadgets[GDX_File241],TSMorphWnd,NULL,
GTST_String, "", TAG_END );
GT_SetGadgetAttrs(TSMorphGadgets[GDX_File242],TSMorphWnd,NULL,
GTST_String, "", TAG_END );
GT_SetGadgetAttrs(TSMorphGadgets[GDX_Name],TSMorphWnd,NULL,
GTST_String, "", TAG_END );
GT_SetGadgetAttrs(TSMorphGadgets[GDX_Frames],TSMorphWnd,NULL,
GTIN_Number,1, TAG_END );
GT_SetGadgetAttrs(TSMorphGadgets[GDX_Start],TSMorphWnd,NULL,
GTIN_Number,0, TAG_END );
SinglePicture = 0;
GT_SetGadgetAttrs(TSMorphGadgets[GDX_SinglePicture],TSMorphWnd,NULL,
GTCY_Active,SinglePicture, TAG_END );
Width = 0;
GT_SetGadgetAttrs(TSMorphGadgets[GDX_Width],TSMorphWnd,NULL,
GTNM_Number,Width, TAG_END );
Height = 0;
GT_SetGadgetAttrs(TSMorphGadgets[GDX_Height],TSMorphWnd,NULL,
GTNM_Number,Height, TAG_END );
MaxWidth = 0;
MaxHeight = 0;
EnableWindows();
return 1;
}
/* Limit the coordinates of a point to the image size */
void
LimitPoints(SHORT *x,SHORT *y,struct Picture *pic) {
if (*x < 0)
*x = 0;
if (*x > pic->ilbm->Bmhd.w-1)
*x = pic->ilbm->Bmhd.w-1;
if (*y < 0)
*y = 0;
if (*y > pic->ilbm->Bmhd.h-1)
*y = pic->ilbm->Bmhd.h-1;
}
static BOOL realfirstcall = TRUE; // Is this really the first call
// not sure I understand this!
// but some parameters (e.g. Public screen) must
// only be set on the very first call
// Initialise all settings values from parameters etc.
void
InitParams(BOOL firstcall) {
UBYTE *omode;
ULONG OZoom = Zoom;
UBYTE *FormatStr;
if (realfirstcall) {
PubScreenName = MyArgString("PUBSCREEN",NULL,!firstcall);
}
if (realfirstcall || !ControlWindow) {
PaletteAllowed = !MatchToolValue(MyArgString("CHANGEPALETTE",PaletteAllowed?"YES":"OFF",!firstcall),"OFF");
ZoomAllowed = !MatchToolValue(MyArgString("ZOOM",ZoomAllowed?"NO":"OFF",!firstcall),"OFF");
}
realfirstcall = FALSE;
strcpy(ScreenName,MyArgString("PUBSCREEN",ScreenName,!firstcall));
strcpy(CustomName,MyArgString("CUSTOMMODE",CustomName,!firstcall));
CustomDepth = MyArgInt("CUSTOMDEPTH",CustomDepth,!firstcall);
strcpy(ScreenNameR,MyArgString("PUBSCREENR",ScreenNameR,!firstcall));
CreateIcons = MatchToolValue(MyArgString("CREATEICONS",CreateIcons?"YES":"NO",!firstcall),"YES");
CreateIconsR = MatchToolValue(MyArgString("CREATEICONSR",CreateIconsR?"YES":"NO",!firstcall),"YES");
CreateIconsP = MatchToolValue(MyArgString("CREATEICONSP",CreateIconsP?"YES":"NO",!firstcall),"YES");
KeepSettings = MatchToolValue(MyArgString("KEEPSETTINGS",KeepSettings?"YES":"NO",!firstcall),"YES");
if (PaletteAllowed) {
palette = MatchToolValue(MyArgString("CHANGEPALETTE",palette?"YES":"NO",!firstcall),"YES");
}
else {
palette = FALSE;
}
if (ZoomAllowed) {
Zoom = (MatchToolValue(MyArgString("ZOOM",Zoom?"YES":"NO",!firstcall),"YES") ? 1 : 0); // Note: not a BOOL
}
else {
Zoom = FALSE;
}
switch (OpenMode) {
case OPEN_ILBM_IF_ILBM:
omode = "IFILBM";
break;
case OPEN_ILBM_ALWAYS:
omode = "ALWAYS";
break;
case OPEN_REMAP:
omode = "REMAP";
break;
case OPEN_OPAL:
omode = "OPAL";
break;
default:
omode = "IFCOLOURS";
break;
}
omode = MyArgString("OPENMODE",omode,!firstcall);
if (MatchToolValue(omode,"IFILBM")) {
OpenMode = OPEN_ILBM_IF_ILBM;
}
else {
if (MatchToolValue(omode,"ALWAYS")) {
OpenMode = OPEN_ILBM_ALWAYS;
}
else {
if (MatchToolValue(omode,"REMAP")) {
OpenMode = OPEN_REMAP;
}
else {
if (MatchToolValue(omode,"OPAL")) {
OpenMode = OPEN_OPAL;
}
else {
OpenMode = OPEN_ILBM_IF_COLOURS;
}
}
}
}
switch (SaveFormat) {
case MI_OPAL24:
FormatStr = "OPAL24";
break;
case MI_OPAL24T:
FormatStr = "OPAL24T";
break;
case MI_OPAL24F:
FormatStr = "OPAL24F";
break;
case MI_OPAL24FT:
FormatStr = "OPAL24FT";
break;
case MI_JPEG:
FormatStr = "JPEG";
break;
case MI_JPEGT:
FormatStr = "JPEGT";
break;
case MI_PBM:
FormatStr = "PPM";
break;
case MI_BW16:
FormatStr = "BW16";
break;
case MI_BW256:
FormatStr = "BW256";
break;
case MI_HAM6:
FormatStr = "HAM6";
break;
case MI_HAM8:
FormatStr = "HAM8";
break;
case MI_DCTV3:
FormatStr = "DCTV3";
break;
case MI_DCTV4:
FormatStr = "DCTV4";
break;
default:
FormatStr = "ILBM24";
break;
}
FormatStr = MyArgString("SAVEFORMAT",FormatStr,!firstcall);
if (MatchToolValue(FormatStr,"OPAL24")) {
SaveFormat = MI_OPAL24;
}
else {
if (MatchToolValue(FormatStr,"OPAL24T")) {
SaveFormat = MI_OPAL24T;
}
else {
if (MatchToolValue(FormatStr,"OPAL24F")) {
SaveFormat = MI_OPAL24F;
}
else {
if (MatchToolValue(FormatStr,"OPAL24FT")) {
SaveFormat = MI_OPAL24FT;
}
else {
if (MatchToolValue(FormatStr,"JPEG")) {
SaveFormat = MI_JPEG;
}
else {
if (MatchToolValue(FormatStr,"JPEGT")) {
SaveFormat = MI_JPEGT;
}
else {
if (MatchToolValue(FormatStr,"PPM")) {
SaveFormat = MI_PBM;
}
else {
if (MatchToolValue(FormatStr,"BW16")) {
SaveFormat = MI_BW16;
}
else {
if (MatchToolValue(FormatStr,"BW256")) {
SaveFormat = MI_BW256;
}
else {
if (MatchToolValue(FormatStr,"HAM6")) {
SaveFormat = MI_HAM6;
}
else {
if (MatchToolValue(FormatStr,"HAM8")) {
SaveFormat = MI_HAM8;
}
else {
if (MatchToolValue(FormatStr,"DCTV3")) {
SaveFormat = MI_DCTV3;
}
else {
if (MatchToolValue(FormatStr,"DCTV4")) {
SaveFormat = MI_DCTV4;
}
else {
SaveFormat = MI_ILBM24;
}
}
}
}
}
}
}
}
}
}
}
}
}
Quality = MyArgInt("QUALITY",Quality,!firstcall);
strcpy(PreScript,MyArgString("PRESCRIPT",PreScript,!firstcall));
strcpy(PostScript,MyArgString("POSTSCRIPT",PostScript,!firstcall));
strcpy(LoadScript,MyArgString("LOADSCRIPT",LoadScript,!firstcall));
strcpy(PreviewScript,MyArgString("PREVIEW",PreviewScript,!firstcall));
DX = MyArgInt("DX",DX,!firstcall);
DY = MyArgInt("DY",DY,!firstcall);
Depth = MyArgInt("DEPTH",Depth,!firstcall);
RenderMode = MyArgInt("MODE",RenderMode,!firstcall);
AntiAlias = MatchToolValue(MyArgString("ANTIALIAS",AntiAlias?"YES":"NO",!firstcall),"YES");
GHelp = MatchToolValue(MyArgString("HELP",GHelp?"YES":"NO",!firstcall),"YES");
// Update with the new parameters
UpdateParams(OZoom);
}
// Update to new settings - OZoom is old zoom mode
void
UpdateParams(ULONG OZoom) {
// remove all the menus
RemoveMenus();
// change all the menu items
SwitchMenuItem(MM_PALETTE,palette,FALSE);
if (ZoomAllowed && (Zoom != OZoom)) {
// If windows are open and changing zoom then update the zoom
if (ControlWindow) {
DisableWindows(DI_Zoom);
if (OZoom) {
UnZoom();
}
else {
ReZoom();
}
EnableWindows();
}
SwitchMenuItem(MM_ZOOM,Zoom,FALSE);
}
UpdateOpenMode(FALSE);
SwitchMenuItem(MM_ICONSR,CreateIconsR,FALSE);
SwitchMenuItem(MM_ICONSP,CreateIconsP,FALSE);
SwitchMenuItem(MM_KEEPS,KeepSettings,FALSE);
SwitchMenuItem(MM_ANTIALIAS,AntiAlias,FALSE);
SwitchMenuItem(MM_HELP,GHelp,FALSE);
UpdateRenderMode(FALSE);
UpdateSaveFormat(FALSE);
// Add the menus back
AddMenus();
// and disable/enable items
if (PaletteAllowed) {
if (TSMorphWnd) {
OnMenu(TSMorphWnd,FULLMENUNUM(1,MM_PALETTE,NOSUB));
}
if (ControlWindow) {
OnMenu(ControlWindow,FULLMENUNUM(M_SETTINGS,MM_PALETTE,NOSUB));
}
}
else {
if (TSMorphWnd) {
OffMenu(TSMorphWnd,FULLMENUNUM(1,MM_PALETTE,NOSUB));
}
if (ControlWindow) {
OffMenu(ControlWindow,FULLMENUNUM(M_SETTINGS,MM_PALETTE,NOSUB));
}
}
if (ZoomAllowed) {
if (TSMorphWnd) {
OnMenu(TSMorphWnd,FULLMENUNUM(1,MM_ZOOM,NOSUB));
}
if (ControlWindow) {
OnMenu(ControlWindow,FULLMENUNUM(M_SETTINGS,MM_ZOOM,NOSUB));
}
}
else {
if (TSMorphWnd) {
OffMenu(TSMorphWnd,FULLMENUNUM(1,MM_ZOOM,NOSUB));
}
if (ControlWindow) {
OffMenu(ControlWindow,FULLMENUNUM(M_SETTINGS,MM_ZOOM,NOSUB));
}
}
}
/* Preview render
* Basically calls ARexx script with parameters - frame number and filename
*/
int
Preview(void) {
UBYTE buffer[140];
UBYTE buffer1[256];
// save first if not saved
if (!Saved) {
if (!SaveRequester()) {
return 1;
}
}
if (GetFrameNumber()) { // Get the frame number
SaveSettings("T:TSMorph.prefs"); // save temporary settings
DisableWindows(DI_Preview); // disable all windows
strcpy(buffer,PreviewScript); // call ARexx script
strcat(buffer," %ld %s");
sprintf(buffer1,buffer,FrameNumber,savedfilename);
SendRxMsg(buffer1,FALSE);
EnableWindows(); // and re-enable windows
return 1;
}
return 1;
}
/* Tries to execute a Rexx script
* msgtxt = name of script
* IgnoreError = TRUE then do not display error message
* Returns: error message
*/
LONG
SendRxMsg(char *msgtxt,BOOL IgnoreError) {
struct MsgPort *reply_port;
struct MsgPort *rx_port;
struct RexxMsg *rx_msg;
LONG ret = RC_FATAL;
if (reply_port = CreateMsgPort()) {
if (rx_msg = CreateRexxMsg(reply_port,"TSM","REXX")) {
rx_msg->rm_Args[0] = msgtxt;
if (FillRexxMsg(rx_msg,1,0)) {
rx_msg->rm_Action = RXCOMM;
Forbid();
if (rx_port = (struct MsgPort *)FindPort("REXX")) {
PutMsg(rx_port, (struct Message *)rx_msg);
Permit();
WaitPort(reply_port);
ReplyMsg(GetMsg(reply_port));
ret = rx_msg->rm_Result1;
}
else {
Permit();
}
ClearRexxMsg(rx_msg, 1);
}
DeleteRexxMsg(rx_msg);
}
DeleteMsgPort(reply_port);
}
// Display an error message (if required)
if (!IgnoreError && ret) {
Error("Error sending ARexx message\n'%s'","OK",msgtxt,H_Arexx);
}
return ret;
}
struct Screen *myscreen = NULL;
/* Opens a custom screen
* Public Screen name is ScreenName
* Mode name is CustomName
* Depth is CustomDepth
* Most other stuff is cloned from the WorkBench
*
* This whole thing needs redoing a bit
*/
BOOL
OpenCustomScreen(void) {
struct Screen *Screen;
struct NameInfo buff;
ULONG id = INVALID_ID;
ULONG myid = INVALID_ID;
BOOL used[256] = {0,0,0,0,0,0,0,0, // table of in use palette entry
0,0,0,0,0,0,0,0, // we use the rest for grey scale
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
};
UWORD numcols;
UWORD i;
UWORD diff;
UBYTE Color;
UWORD rgb;
BOOL usedri = TRUE;
UWORD mydir = ~0;
struct DrawInfo *dri = NULL;
struct DrawInfo *mydri = NULL;
BOOL retflag = TRUE;
char *emsg;
char *e1=NULL;
ULONG err=0;
// check we have a name and a mode and depth
if (ScreenName && *ScreenName && CustomName && *CustomName && (CustomDepth > 0)) {
// check public screen not already open
if (!(Screen = LockPubScreen(ScreenName))) {
// try and find modeid
id = NextDisplayInfo(id);
while ((id != INVALID_ID) && (myid == INVALID_ID)) {
if (GetDisplayInfoData(NULL,(UBYTE *)&buff,sizeof(struct NameInfo),DTAG_NAME,id)) {
if (!Stricmp(buff.Name,CustomName)) {
myid = id;
}
}
id = NextDisplayInfo(id);
}
if (myid != INVALID_ID) {
// Get info from the workbench
if (Screen = LockPubScreen("Workbench")) {
if (dri = GetScreenDrawInfo(Screen)) {
for (i = 0;
i < dri->dri_NumPens;
++i) {
if (!(dri->dri_Pens[i] < (1<<CustomDepth))) {
usedri = FALSE;
}
}
// open sort of cloned screen
if (myscreen = OpenScreenTags(NULL,
SA_Depth, CustomDepth,
SA_Overscan, OSCAN_TEXT,
SA_Pens, usedri?((ULONG) (dri->dri_Pens)):((ULONG) &mydir),
SA_SysFont, 1,
SA_DisplayID, myid,
SA_Type, PUBLICSCREEN,
SA_PubName, ScreenName,
SA_Title, ScreenName,
SA_FullPalette, TRUE,
TAG_END)) {
// set unused palette entries to grey scale
if (mydri = GetScreenDrawInfo(myscreen)) {
numcols = 1<<CustomDepth;
for (i = 0;
i < mydri->dri_NumPens;
++i) {
if (!used[min(mydri->dri_Pens[i],256)]) {
used[min(mydri->dri_Pens[i],256)] = TRUE;
--numcols;
}
}
if (numcols) {
diff = (16 / (numcols + 1));
Color = diff;
if (!diff) {
diff = 1;
}
for (i = 0;
(i < (1<<CustomDepth));
++i) {
if (!used[i] && (Color<16)) {
SetRGB4(&(myscreen->ViewPort),i,Color,Color,Color);
Color += diff;
}
else {
if (i < (1<< dri->dri_Depth)) {
rgb = GetRGB4(Screen->ViewPort.ColorMap,i);
SetRGB4(&(myscreen->ViewPort),i,rgb>>8,(rgb & 0x0f0)>>4,rgb & 0x0f);
}
}
}
}
// Free everything, set screen to public and return
FreeScreenDrawInfo(myscreen,mydri);
}
PubScreenStatus(myscreen,NULL);
FreeScreenDrawInfo(Screen,dri);
UnlockPubScreen(NULL,Screen);
OpenedScreen = TRUE;
return TRUE;
}
// Free everything and display error
else {
retflag = FALSE;
emsg = "Error opening screen";
err = HE_OScreen;
}
FreeScreenDrawInfo(Screen,dri);
}
else {
retflag = FALSE;
emsg = "Unable to get DrawInfo";
err = HE_DrawI;
}
UnlockPubScreen(NULL,Screen);
}
else {
retflag = FALSE;
emsg = "Unable to lock Workbench";
err = HE_LockW;
}
}
else {
retflag = FALSE;
emsg = "Invalid screen mode %s";
e1 = CustomName;
err = HE_ScreenMode;
}
}
else {
UnlockPubScreen(NULL,Screen);
}
}
if (!retflag) {
Error(emsg,"Quit",e1,err);
}
return retflag;
}
/* Attempt to close the public screen
*
* This really is a horrible hack
* we just loop for a while (not busy waiting)
* and then give up. This may leave the screen open
* with a title pointing to unallocated memory.
*
* This should be based on the Signal when last window is shut!
*/
void
CloseCustomScreen(void) {
int i;
for (i=0; i < 20; ++i) {
if (CloseScreen(myscreen)) {
break;
}
Delay(50);
}
}